package com.css.bjdt_core.util;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.UUID;

/**
 * 工具�?- 公用
 */

public class CommonUtil {

	/**
	 * 随机获取UUID字符�?无中划线)
	 * 
	 * @return UUID字符�?
	 */
	public static String getUUID() {
		String uuid = UUID.randomUUID().toString();
		return uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23)
				+ uuid.substring(24);
	}

	/**
	 * 随机获取字符�?
	 * 
	 * @param length
	 *            随机字符串长�?
	 * 
	 * @return 随机字符�?
	 */
	public static String getRandomString(int length) {
		if (length <= 0) {
			return "";
		}
		char[] randomChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
				'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm' };
		Random random = new Random();
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < length; i++) {
			stringBuffer.append(randomChar[Math.abs(random.nextInt()) % randomChar.length]);
		}
		return stringBuffer.toString();
	}

	/**
	 * 根据指定长度 分隔字符�?
	 * 
	 * @param str
	 *            �?��处理的字符串
	 * @param length
	 *            分隔长度
	 * 
	 * @return 字符串集�?
	 */
	public static List<String> splitString(String str, int length) {
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < str.length(); i += length) {
			int endIndex = i + length;
			if (endIndex <= str.length()) {
				list.add(str.substring(i, i + length));
			} else {
				list.add(str.substring(i, str.length() - 1));
			}
		}
		return list;
	}

	/**
	 * 将字符串List转化为字符串，以分隔符间�?
	 * 
	 * @param list
	 *            �?��处理的List.
	 *            
	 * @param separator
	 *            分隔�?
	 * 
	 * @return 转化后的字符�?
	 */
	public static String toString(List<String> list, String separator) {
		StringBuffer stringBuffer = new StringBuffer();
		for (String str : list) {
			stringBuffer.append(separator + str);
		}
		stringBuffer.deleteCharAt(0);
		return stringBuffer.toString();
	}

	public static String convertIDList(Collection<String> ids) {
		if (ids == null || ids.size() == 0) {
			return "''";
		} else {
			StringBuilder res = new StringBuilder();
			for (String id : ids) {
				res.append("'").append(id).append("',");
			}
			if (res.length() > 0) {
				return res.substring(0, res.length() - 1);
			} else {
				return "''";
			}
		}
	}

	/**
	 * 将list按blockSize大小等分，最后多余的单独一份
	 *
	 * @param list
	 * @param blockSize
	 * @return
	 */
	public static <T> List<List<T>> subList(List<T> list, int blockSize) {
		List<List<T>> lists = new ArrayList<List<T>>();
		if (list != null && blockSize > 0) {
			int listSize = list.size();
			if (listSize <= blockSize) {
				lists.add(list);
				return lists;
			}
			int batchSize = listSize / blockSize;
			int remain = listSize % blockSize;
			for (int i = 0; i < batchSize; i++) {
				int fromIndex = i * blockSize;
				int toIndex = fromIndex + blockSize;
				lists.add(list.subList(fromIndex, toIndex));
			}
			if (remain > 0) {
				lists.add(list.subList(listSize - remain, listSize));
			}
		}
		return lists;
	}

	//将每�?��字母都塞进MAP里，然后未来通过字母可以取得对应的列�?
	public static String[] letterArray = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
			"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

	/**
	 * 将字母转化成数字
	 * 
	 * @param letterStr �?��转化的字�?
	 */
	public static String letterToNum(String letterStr) {
		String letterStrNew = letterStr.toUpperCase();
		String[] letterArrayNew = letterStrNew.split("");
		BigDecimal bdNum = new BigDecimal(0);

		if (letterArrayNew.length == 1) {
			bdNum = bdNum.add(new BigDecimal(letterArrayNew[0].hashCode()).subtract(new BigDecimal(64)));
		}
		/*因为截完字符串之后，数组第一个是个空格，�?��从数组第二个�?��取，如果数组长度�?，说明就�?��字母，直接进行转化就行，如果数组长度不是2�?
		说明类似这种AB,AAB等，这就要找到数组的�?���?��，然后对�?���?��进行转换，再加上26*/
		else if (letterArrayNew.length <= 2) {
			bdNum = bdNum.add(new BigDecimal(letterArrayNew[1].hashCode()).subtract(new BigDecimal(64)));
		} else {
			BigDecimal a = (new BigDecimal(letterArrayNew.length).subtract(new BigDecimal(2)))
					.multiply(new BigDecimal(26));
			String lastLetter = letterArrayNew[letterArrayNew.length - 1];
			bdNum = bdNum.add(new BigDecimal(lastLetter.hashCode()).subtract(new BigDecimal(64))).add(a);
		}
		return bdNum.toString();
	}

	/**
	 * 将数字转换成字母
	 * 
	 * @param numStr �?��转化的数�?
	 */
	public static String numToLetter(String numStr) {
		Integer num = Integer.parseInt(numStr);
		Integer a = new BigDecimal(num).divideToIntegralValue(new BigDecimal(27)).intValue();
		if (a > 0) {
			Integer b = new BigDecimal(num).subtract(new BigDecimal(26).multiply(new BigDecimal(a))).intValue();
			String letter = "";
			for (int c = 0; c < a; c++) {
				letter += "A";
			}
			letter += letterArray[b - 1];
			return letter;
		} else {
			return letterArray[num - 1];
		}
	}

	//将一个坐标转换成数字坐标，例如A1转换成1,1,传出去的值为 1,1 第一个是列，第二个是行
	public static String coordinateChange(String coordinate) {
		String str = coordinate.replaceAll("\\d+", "");
		//String str = coordinate.replaceAll("[^a-zA-Z].+$", "");
		String num = coordinate.replaceAll("[^0-9]", "");
		return letterToNum(str) + "," + num;
	}

	//将一个坐标转换成数字坐标，例如A1转换成1,1,传出去的值为 1_1 第一个是列，第二个是行
	public static String coordinateChangeOther(String coordinate) {
		String str = coordinate.replaceAll("\\d+", "");
		//String str = coordinate.replaceAll("[^a-zA-Z].+$", "");
		String num = coordinate.replaceAll("[^0-9]", "");
		return letterToNum(str) + "_" + num;
	}

	//将一个坐标转换成数字坐标，例如A1转换成1,1,传出去的值为 1_1 第一个是行，第二个是列
	public static String coordinateChangeOtherRowCol(String coordinate) {
		String str = coordinate.replaceAll("\\d+", "");
		//String str = coordinate.replaceAll("[^a-zA-Z].+$", "");
		String num = coordinate.replaceAll("[^0-9]", "");
		return num + "_" + letterToNum(str);
	}

	//读取配置文件中的报表模板的存储URL
	public static String readProperties() {
		Properties prop = new Properties();
		//读取属�?文件a.properties
		try {
			InputStream in = CommonUtil.class.getResourceAsStream("/upload.properties");
			prop.load(in); ///加载属�?列表
			in.close();
			return prop.getProperty("cellUploadUrl");
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	/**
	 * 判断传入对象是否为空
	 * 
	 * @param obj �?��判断的是对象
	 */
	public static boolean isNullOrEmpty(Object obj) {
		if (obj == null) {
			return true;
		} else {
			return false;
		}
	}

	//读取配置文件中的数据导出的临时文件存放路径
	public static String readExportTempUrl() {
		Properties prop = new Properties();
		//读取属性文件a.properties
		try {
			//InputStream in = new BufferedInputStream(new FileInputStream("upload.properties"));
			InputStream in = CommonUtil.class.getResourceAsStream("/upload.properties");
			prop.load(in); ///加载属性列表
			in.close();
			return prop.getProperty("dataReportTemp");
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	//读取配置文件中的导出数据表
	public static String readPropertiesExportTable() {
		Properties prop = new Properties();
		//读取属性文件a.properties
		try {
			//InputStream in = new BufferedInputStream(new FileInputStream("upload.properties"));
			InputStream in = CommonUtil.class.getResourceAsStream("/upload.properties");
			prop.load(in); ///加载属性列表
			in.close();
			return prop.getProperty("exportTable");
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	//读取配置文件中的导入文件的上传路径
	public static String readReportDataUploadUrl() {
		Properties prop = new Properties();
		//读取属性文件a.properties
		try {
			//InputStream in = new BufferedInputStream(new FileInputStream("upload.properties"));
			InputStream in = CommonUtil.class.getResourceAsStream("/upload.properties");
			prop.load(in); ///加载属性列表
			in.close();
			return prop.getProperty("dataReportUpload");
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	public static String readPropertiesTable(String tableName) {
		Properties prop = new Properties();
		//读取属性文件a.properties
		try {
			InputStream in = CommonUtil.class.getResourceAsStream("/table.properties");
			prop.load(in); ///加载属性列表
			in.close();
			return prop.getProperty(tableName);
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	public static String readUploadPropertiesTable(String tableName) {
		Properties prop = new Properties();
		//读取属性文件a.properties
		try {
			InputStream in = CommonUtil.class.getResourceAsStream("/upload.properties");
			prop.load(in); ///加载属性列表
			in.close();
			return prop.getProperty(tableName);
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
	}

	public static String uuidShorter(String s) {
		String temp = s.indexOf("-") > 0 ? s : addDashForUUID(s);
		UUID uuid = UUID.fromString(temp);
		StringBuilder sb = new StringBuilder();
		sb.append(digits(uuid.getMostSignificantBits() >> 32, 8));
		sb.append(digits(uuid.getMostSignificantBits() >> 16, 4));
		sb.append(digits(uuid.getMostSignificantBits(), 4));
		sb.append(digits(uuid.getLeastSignificantBits() >> 48, 4));
		sb.append(digits(uuid.getLeastSignificantBits(), 12));
		return sb.toString();
	}

	private static String digits(long val, int digits) {
		long hi = 1L << (digits * 4);
		return Numbers.toString(hi | (val & (hi - 1)), Numbers.MAX_RADIX).substring(1);
	}

	private static String addDashForUUID(String uuid) {
		StringBuilder res = new StringBuilder();
		res.append(uuid.substring(0, 8)).append("-").append(uuid.substring(8, 12)).append("-")
				.append(uuid.substring(12, 16)).append("-").append(uuid.substring(16, 20)).append("-")
				.append(uuid.substring(20));
		return res.toString();
	}

	private static class Numbers {

		final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', /*'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
																							'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
																							'z', */'A', 'B', 'C', 'D', 'E',
				'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
				'Z' };

		final static Map<Character, Integer> digitMap = new HashMap<Character, Integer>();

		static {
			for (int i = 0; i < digits.length; i++) {
				digitMap.put(digits[i], (int) i);
			}
		}

		/**
		 * 支持的最大进制数
		 */
		public static final int MAX_RADIX = digits.length;

		/**
		 * 支持的最小进制数
		 */
		public static final int MIN_RADIX = 2;

		/**
		 * 将长整型数值转换为指定的进制数（最大支持62进制，字母数字已经用尽）
		 *
		 * @param i
		 * @param radix
		 * @return
		 */
		public static String toString(long i, int radix) {
			if (radix < MIN_RADIX || radix > MAX_RADIX)
				radix = 10;
			if (radix == 10)
				return Long.toString(i);

			final int size = 65;
			int charPos = 64;

			char[] buf = new char[size];
			boolean negative = (i < 0);

			if (!negative) {
				i = -i;
			}

			while (i <= -radix) {
				buf[charPos--] = digits[(int) (-(i % radix))];
				i = i / radix;
			}
			buf[charPos] = digits[(int) (-i)];

			if (negative) {
				buf[--charPos] = '-';
			}

			return new String(buf, charPos, (size - charPos));
		}

		static NumberFormatException forInputString(String s) {
			return new NumberFormatException("For input string: \"" + s + "\"");
		}

		/**
		 * 将字符串转换为长整型数字
		 *
		 * @param s
		 *            数字字符串
		 * @param radix
		 *            进制数
		 * @return
		 */
		public static long toNumber(String s, int radix) {
			if (s == null) {
				throw new NumberFormatException("null");
			}

			if (radix < MIN_RADIX) {
				throw new NumberFormatException("radix " + radix + " less than Numbers.MIN_RADIX");
			}
			if (radix > MAX_RADIX) {
				throw new NumberFormatException("radix " + radix + " greater than Numbers.MAX_RADIX");
			}

			long result = 0;
			boolean negative = false;
			int i = 0, len = s.length();
			long limit = -Long.MAX_VALUE;
			long multmin;
			Integer digit;

			if (len > 0) {
				char firstChar = s.charAt(0);
				if (firstChar < '0') {
					if (firstChar == '-') {
						negative = true;
						limit = Long.MIN_VALUE;
					} else if (firstChar != '+')
						throw forInputString(s);

					if (len == 1) {
						throw forInputString(s);
					}
					i++;
				}
				multmin = limit / radix;
				while (i < len) {
					digit = digitMap.get(s.charAt(i++));
					if (digit == null) {
						throw forInputString(s);
					}
					if (digit < 0) {
						throw forInputString(s);
					}
					if (result < multmin) {
						throw forInputString(s);
					}
					result *= radix;
					if (result < limit + digit) {
						throw forInputString(s);
					}
					result -= digit;
				}
			} else {
				throw forInputString(s);
			}
			return negative ? result : -result;
		}

	}

	public static void main(String[] args) {
		String[] uuids = { "c6bc92d24c314b63adf98ff3e7de66c1" };
		for (String s : uuids) {
			System.out.println(s + " -- " + uuidShorter(s));
		}
	}

	/**
	 * 根据身份编号获取年龄
	 *
	 * @param idCard
	 *            身份编号
	 * @return 年龄
	 */
	public static int getAgeByIdCard(String idCard) {
		try {
			int iAge = 0;
			Calendar cal = Calendar.getInstance();
			String year = idCard.substring(6, 10);
			int iCurrYear = cal.get(Calendar.YEAR);
			iAge = iCurrYear - Integer.valueOf(year);
			return iAge;
		} catch (Exception e) {
			return 0;
		}
	}

	public static String toChinese(String string) {
		String[] s1 = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
		String[] s2 = { "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千" };

		String result = "";

		int n = string.length();
		for (int i = 0; i < n; i++) {

			int num = string.charAt(i) - '0';

			if (i != n - 1 && num != 0) {
				result += s1[num] + s2[n - 2 - i];
			} else {
				result += s1[num];
			}
			/*System.out.println("  " + result);*/
		}

		/*System.out.println("----------------");
		System.out.println(result);*/
		return result;

	}

	//由日期计算出年龄
	public static String getAge(String birthDayStr) throws Exception {
		try {
			//想将字符串转换成日期格式
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date birthDay = sdf.parse(birthDayStr);

			Calendar cal = Calendar.getInstance();

			if (cal.before(birthDay)) {
				throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
			}
			int yearNow = cal.get(Calendar.YEAR);
			int monthNow = cal.get(Calendar.MONTH);
			int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
			cal.setTime(birthDay);

			int yearBirth = cal.get(Calendar.YEAR);
			int monthBirth = cal.get(Calendar.MONTH);
			int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

			int age = yearNow - yearBirth;

			if (monthNow <= monthBirth) {
				if (monthNow == monthBirth) {
					if (dayOfMonthNow < dayOfMonthBirth)
						age--;
				} else {
					age--;
				}
			}
			return age + "";
		} catch (Exception e) {
			e.printStackTrace();
			return "--";
		}

	}
}